//-------------------------------------------------------------------------------------------------
// Copyright (c) Bradford W. Mott and Flare Contributors
// North Carolina State University, Department of Computer Science
// The IntelliMedia Group
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
// SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//-------------------------------------------------------------------------------------------------

using Flare.Geom;
using System.Collections.Generic;

namespace Flare.Display
{
    /// <summary>
    /// The GraphicsPath class defines a collection of drawing commands and their
    /// corresponding parameters.
    /// </summary>
    public class GraphicsPath
    {
        /// <summary>
        /// Collection of drawing commands defining the path. Each command is an
        /// integer value from the GraphicsPathCommand class.
        /// </summary>
        public List<int> commands { get; set; }

        /// <summary>
        /// Collection of parameters used with the drawing commands.
        /// </summary>
        public List<float> data { get; set; }

        /// <summary>
        /// Winding rule to use for the path (value from the GraphicsPathWinding class).
        /// </summary>
        public string winding { get; set; }

        /// <summary>
        /// Create a graphics path using the specified values.
        /// </summary>
        public GraphicsPath(List<int> commands = null, List<float> data = null,
            string winding = GraphicsPathWinding.EVEN_ODD)
        {
            this.commands = commands;
            this.data = data;
            this.winding = winding;
        }

        /// <summary>
        /// Create a copy of the specified graphics path.
        /// </summary>
        public GraphicsPath(GraphicsPath path)
        {
            this.commands = new List<int>(path.commands);
            this.data = new List<float>(path.data);
            this.winding = path.winding;
        }

        /// <summary>
        /// Add a curve segment to the path defined by the specified values.
        /// </summary>
        public void CurveTo(float controlX, float controlY, float anchorX, float anchorY)
        {
            if (this.commands == null)
            {
                this.commands = new List<int>();
            }
            if (this.data == null)
            {
                this.data = new List<float>();
            }

            this.commands.Add(GraphicsPathCommand.CURVE_TO);
            this.data.Add(controlX);
            this.data.Add(controlY);
            this.data.Add(anchorX);
            this.data.Add(anchorY);
        }

        /// <summary>
        /// Add a line segment to the path defined by the specified values.
        /// </summary>
        public void LineTo(float x, float y)
        {
            if (this.commands == null)
            {
                this.commands = new List<int>();
            }
            if (this.data == null)
            {
                this.data = new List<float>();
            }

            this.commands.Add(GraphicsPathCommand.LINE_TO);
            this.data.Add(x);
            this.data.Add(y);
        }

        /// <summary>
        /// Move to a new position to start the next segment of the path.
        /// </summary>
        public void MoveTo(float x, float y)
        {
            if (this.commands == null)
            {
                this.commands = new List<int>();
            }
            if (this.data == null)
            {
                this.data = new List<float>();
            }

            this.commands.Add(GraphicsPathCommand.MOVE_TO);
            this.data.Add(x);
            this.data.Add(y);
        }
    }
}
